#include <iostream>

#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;


//这个Pass遍历函数中的每个基本块（BasicBlock），并在每个基本块的开头插入一条print语句，输出基本块的名称。

namespace {
    // 定义HelloWorldPass类，继承自FunctionPass类
    struct HelloWorldPass : public FunctionPass {
        static char ID;
        HelloWorldPass() : FunctionPass(ID) {}

        // 重写runOnFunction函数，遍历函数中的每个基本块
        bool runOnFunction(Function &F) override {
            for (auto &BB : F) {
                errs() << "Hello from " << BB.getName() << "!\n";
            }
            return false;
        }
    };
}

char HelloWorldPass::ID = 0;

// 注册HelloWorldPass
static RegisterPass<HelloWorldPass> X("hello", "Hello World Pass");

//定义了一个继承自FunctionPass类的HelloWorldPass类。FunctionPass是LLVM中Pass的基类，它提供了遍历函数的接口。
// 在HelloWorldPass类中，我们实现了runOnFunction函数，这个函数会被自动调用，遍历函数中的每个基本块，输出基本块的名称。
// 最后，我们使用LLVM提供的RegisterPass宏将HelloWorldPass注册到LLVM中，这样就可以在LLVM中使用这个Pass了。
//在实际使用中，我们需要将这个代码保存为.h和.cpp文件，然后编译成LLVM插件，加载到LLVM中使用。可以使用cmake或Makefile等工具进行编译。编译完成后，使用opt工具加载插件，执行命令行：
// opt -load path/to/HelloWorldPass.so -hello input.ll -o output.ll
// 其中，-load选项用于加载插件，-hello选项是我们自定义的选项，用于指定要进行处理的文件，-o选项用于指定输出文件。执行完成后，output.ll文件中就包含了我们插入的print语句。

